package net.ojbk.sso.center.beans.pojo;

import net.ojbk.sso.center.beans.po.ClientWebsite;
import net.ojbk.sso.center.beans.vo.VO_LoggedWebsites;
import net.ojbk.sso.center.exception.TokenSystemException;
import net.ojbk.sso.center.util.UUIDTool;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Configuration;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: twobox
 * Date: 2019/3/23
 * Time: 21:26
 * Description: 通过token操作用户的登陆状态等。
 * 2、一种token对应HttpSession的维护对象
 */
@Configuration
public class TokenSystem {
    private Logger logger = Logger.getLogger(TokenSystem.class);

    private HashMap<String, OjbkSession> ojbkSessionMap;

    // 0 构造器
    public TokenSystem() {
        this.ojbkSessionMap = new HashMap<String, OjbkSession>();
        logger.info("开始创建session时间同步多线程。");
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    maintainAllOjbkSession();
                    try {
                        Thread.sleep(1 * 60000);
                    } catch (InterruptedException e) {
                        logger.error(e.getMessage());
                    }
                }
            }
        }).start();
        logger.info("创建session时间同步多线程完毕。");
    }

    // 1 工具类
    private String getNewToken() {
        return UUIDTool.getNewUUID();
    }

    // 2 动作
    // 2.1 使用账号密码登陆center，创建OjbkSession会话并维护
    public void fastLogin(HttpSession session) {
        // 生成一个token of uuid.
        String token = this.getNewToken();
        OjbkSession ojbkSession = OjbkSession.createNewOjbkSession(session, token);
        this.ojbkSessionMap.put(token, ojbkSession);
    }

    // 2.2 登陆一个子网站
    public void loginAWeb(String token, ClientWebsite clientWebsite) throws TokenSystemException {
        OjbkSession ojbkSession = getOjbkSession_ByToken(token);
        ojbkSession.addOneClientWebsite(clientWebsite);
    }

    // 2.3 注销所有网站,通过token
    public void logoutAllClientWebsite(String token) throws Exception {
        // 所有子网站注销HttpSession
        OjbkSession ojbkSession = getOjbkSession_ByToken(token);
        ojbkSession.logoutAllWebsite();
        // 维护Map集合
        ojbkSessionMap.remove(token);
        // log
        logger.debug("用户（" + token + "）：注销了全部子网站！");
    }

    // 2.4 维护所有OjbkSession会话
    public void maintainAllOjbkSession() {
        for (Map.Entry<String, OjbkSession> vo : ojbkSessionMap.entrySet()) {
            try {
                logger.debug("Maintain " + vo.getKey() + "'s  OjbkSession .");
                vo.getValue().maintainAllClientWebsite();
            } catch (IllegalStateException e) {
                try {
                    logger.info("检测到失效的OjbkSession：" + vo.getKey());
                    this.ojbkSessionMap.remove(vo.getKey());
                } catch (Exception ex) {
                    logger.error(ex.getMessage());
                    ex.printStackTrace();
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
    }

    // 3 获取信息
    public OjbkSession getOjbkSession_ByToken(String token) throws TokenSystemException {
        OjbkSession ojbkSession = ojbkSessionMap.get(token);
        if (ojbkSession == null)
            throw new TokenSystemException("此Token已过期或非法。未查找到OjbkSession。");
        return ojbkSession;
    }

    public HttpSession getHttpSession_ByToken(String token) throws TokenSystemException {
        return getOjbkSession_ByToken(token).getHttpSession();
    }

    public String getToken_ByHttpSession(HttpSession session) throws TokenSystemException {
        String token = (String) session.getAttribute("token");
        if (token == null || token.equals("")) {
            throw new TokenSystemException("此session无效，未注册过Token。");
        }
        return token;
    }

    public List<VO_LoggedWebsites> getAllloggedWeb(String token) throws TokenSystemException {
        return getOjbkSession_ByToken(token).getAllLoggedWeb();
    }

    public HashMap<String, OjbkSession> getOjbkSessionMap(String pwd) {
        if (pwd == null || !pwd.equals("100001"))
            return null;
        return ojbkSessionMap;
    }
}
